<template>
  <BasicModal
    :visible="visible"
    title="选择父节点"
    :loading="loading"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <a-tree
      v-model:expanded-keys="expandedKeys"
      v-model:selected-keys="selectedKeys"
      v-model:checked-keys="checkedKeys"
      :tree-data="treeData"
      :checkable="false"
      :checkStrictly="true"
      :defaultExpandAll="true"
      show-icon
    >
      <template #switcherIcon="{ switcherCls }">
        <down-outlined :class="switcherCls" />
      </template>
      <template #icon="{ type }">
        <template v-if="type === 'system'">
          <appstore-add-outlined />
        </template>
        <template v-else>
          <database-outlined />
        </template>
      </template>
    </a-tree>
  </BasicModal>
</template>

<script>
  import { Tree, message } from 'ant-design-vue'
  import { useRouter } from 'vue-router'
  import { getDescendants } from '/@/api/module/module'
  import { BasicModal } from '/@/components/Modal'
  import { useModuleStoreWithOut } from '/@/store/modules/module'
  import { DownOutlined, DatabaseOutlined, AppstoreAddOutlined } from '@ant-design/icons-vue'

  export default {
    components: {
      'a-tree': Tree,
      'down-outlined': DownOutlined,
      'appstore-add-outlined': AppstoreAddOutlined,
      'database-outlined': DatabaseOutlined,
      BasicModal,
    },
    props: {
      visible: Boolean,
      selectedKey: Number,
    },
    emits: ['ok', 'cancel'],
    data() {
      return {
        store: useModuleStoreWithOut(),
        router: useRouter(),
        loading: false,
        treeData: [],
        selectedKeys: [],
        checkedKeys: [],
        expandedKeys: [],
      }
    },
    watch: {
      selectedKeys() {
        console.log('selectedKeys', this.selectedKeys)
      },
      checkedKeys() {
        console.log('checkedKeys', this.checkedKeys)
      },
    },
    mounted() {
      if (this.store.getRoot.id != 0) {
        this.loading = true
        getDescendants({ root: this.store.getRoot.id })
          .then((data) => {
            this.onGetDescendants(data)
          })
          .catch((e) => {
            console.error('get child nodes failed:', e)
            message.error('get child nodes failed')
            this.loading = false
          })
      }
    },
    methods: {
      handleCancel: function () {
        this.$emit('cancel')
      },
      handleOk: function () {
        let node = this.findNodeDataByKey(this.selectedKeys[0], this.treeData)
        this.$emit('ok', node)
      },
      onNodeChecked(node) {
        console.log(node)
      },
      onGetDescendants(data) {
        let root = {
          title: data.parent.name,
          key: data.parent.moduleId,
          type: data.parent.moduleType,
          desc: data.parent.desc,
          children: [],
        }
        this.makeTreeData(root, data.descendants)
        this.treeData.push(root)
        this.setSelectedKeys()
        this.setExpandedKeys()
        this.loading = false
      },
      makeTreeData(node, modules) {
        if (!modules || !node) return

        for (let mod of modules) {
          if (mod.parentId === node.key) {
            node.children.push({
              title: mod.name,
              key: mod.moduleId,
              type: mod.moduleType,
              desc: mod.desc,
              children: [],
            })
          }
        }
        for (let child of node.children) {
          this.makeTreeData(child, modules)
        }
      },
      findAncestors(nodes, targetKey, ancestors = []) {
        for (const node of nodes) {
          console.log('node:', node)
          if (node.key === targetKey) {
            return ancestors
          }
          if (node.children) {
            const foundAncestors = this.findAncestors(node.children, targetKey, [
              ...ancestors,
              node,
            ])
            if (foundAncestors.length > 0) {
              return foundAncestors
            }
          }
        }
        return []
      },
      setSelectedKeys() {
        this.selectedKeys.push(this.selectedKey)
      },
      setExpandedKeys() {
        let ancestors = this.findAncestors(this.treeData, this.selectedKey)
        this.expandedKeys = ancestors.map((node) => node.key)
      },
      findNodeDataByKey(key, treeData) {
        for (let i = 0; i < treeData.length; i++) {
          const node = treeData[i]
          if (node.key === key) {
            return node
          } else if (node.children) {
            const result = this.findNodeDataByKey(key, node.children)
            if (result) {
              return result
            }
          }
        }
        return null
      },
    },
  }
</script>
